<template>
  <div class="chat-page">
    <div v-if="route.path === '/hall_chat'" style="margin-top: -5px">
      <van-notice-bar
          left-icon="volume-o"
          scrollable
          color="#1989fa" background="#ecf9ff"
          :text="chartContent"
      />
    </div>
    <div v-if="route.path === '/hall_chat'" style="margin-top: 10px"/>
    <div v-else class="head">
      <p>{{ title_name?.slice(0, 10) }}</p>
    </div>
    <div class="chat_content" ref="chatContent">
      <div class="message" v-for="message in messageList" :key="message.createTime"
           :class="{'my-message': message.isMy, 'other-message': !message.isMy}">
        <!--     展示聊天信息    -->
        <div class="message">
          <div class="avatar">
            <van-image
                round
                :src="message.fromUser?.avatarUrl"
            />
          </div>
          <div class="user-info">
            <p class="title">{{ message.fromUser.username + '&nbsp&nbsp' + message.createTime }}</p>
            <div class="content">{{ message.content }}</div>
          </div>
        </div>
      </div>
    </div>
    <div class="send">
      <van-cell-group inset>
        <van-field class="input"
                   v-model="content"
                   rows="2"
                   type="textarea"

        />
      </van-cell-group>
      <van-button type="primary" @click="send">发送</van-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import "../assets/css/chat.css"
import {useRoute} from "vue-router";
import {chartContent} from "../assets/noticeText/indexNotice";
import {nextTick, onMounted, ref} from "vue";
import {chatMessage, messageRequest} from "../models/chat";
import myAxios from "../plugins/myAxios.ts";
import {ResponseResult} from "../models/resopnse";
import {showFailToast, showToast} from "vant";
import {chatScopeEnum} from "../constants/chat.ts";
import {onlineUsersInfo, userType} from "../models/user";
import {getCurrentUser} from "../services/user.ts";
import {userRole} from "../constants/user.ts";
import dayjs from 'dayjs';

const route = useRoute()

const chatContent = ref<HTMLDivElement | null>(null)

const onlineUsers = ref<onlineUsersInfo>()

const content = ref<string>('')
const title_name = ref<string>()
const messageList = ref<chatMessage[]>([])

const currentUser = ref<userType>()

onMounted(async () => {
  const user = await getCurrentUser()
  if (user) {
    currentUser.value = user
  }
  await loadDate()
  init()
})

const {id, scope, name} = route.query
const loadDate = async () => {
  let res: ResponseResult<chatMessage[]>
  const getMessageList = async () => {
    if (res.code === 0) {
      messageList.value = res.data.filter(Boolean)
      // 调试
    } else {
      showFailToast('加载信息失败')
      showToast(res.description ?? res.message)
    }
  }
  if (route.path === '/hall_chat') {
    res = await myAxios.get('/chat/hallChat')
    await getMessageList()
    return;
  }
  title_name.value = name as string
  // @ts-ignore
  if (scope as number == chatScopeEnum.PRIVATE_CHAT) {
    res = await myAxios.post('/chat/privateChat', {
      toId: id,
    })
    await getMessageList()
  } // @ts-ignore
  else if (scope as number == chatScopeEnum.TEAM_CHAT) {
    res = await myAxios.post('/chat/teamChat', {
      teamId: id
    })
    await getMessageList()
  }
}

let socket: WebSocket
const heartbeatInterval = 30 * 1000 // 30秒
let heartbeatTimer: any = null
const startHeartbeat = () => {
  heartbeatTimer = setInterval(() => {
    if (socket.readyState === WebSocket.OPEN) {
      socket.send("PING");
    }
  }, heartbeatInterval);
}

const stopHeartbeat = () => {
  clearInterval(heartbeatTimer);
  heartbeatTimer = null;
}

const init = () => {
  if (typeof (WebSocket) == "undefined") {
    showFailToast("您的浏览器不支持WebSocket")
    return
  }
  let userId, teamId
  userId = currentUser.value?.id
  // @ts-ignore
  if (scope as number == chatScopeEnum.PRIVATE_CHAT) {
    teamId = NaN
  } // @ts-ignore
  else if (scope as number == chatScopeEnum.TEAM_CHAT) {
    teamId = id
  } else {
    teamId = NaN
  }
  const socketUrl = `ws://localhost:8180/api/websocket/${userId}/${teamId}`
  if (socket != null) {
    socket.close()
  }
  // 开启一个webSocket服务
  socket = new WebSocket(socketUrl)
  socket.onopen = () => {
    startHeartbeat()
    console.log("连接成功")
  }
  // 浏览器接收到来自服务端发过来的消息
  socket.onmessage = (msg) => {
    if (msg.data === 'pong') {
      return
    }
    console.log("收到消息", msg.data)
    // 对接收到的json数据进行解析
    const data = JSON.parse(msg.data)
    if (data.error) {
      showFailToast(data.error)
      return
    }
    console.log("解析后的数据", data)
    if (data.users) {
      // @ts-ignore
      if (scope as number == chatScopeEnum.HALL_CHAT) {
        onlineUsers.value = data.users
      }
    } else {
      const message: chatMessage = data
      messageList.value.push(message)
    }
    // console.log('接收测试', messageList.value)
    // 滚动到最底部
    scrollToBottom()
  }
  // 关闭事件
  socket.onclose = () => {
    console.log("连接关闭")
    stopHeartbeat()
    setTimeout(init, 5000) // 5秒后重连
  }
  socket.onerror = () => {
    console.log("连接发生错误")
  }
}

const send = async () => {
  if (!currentUser.value) {
    showFailToast('请先登录')
    return
  }
  if (typeof (WebSocket) == "undefined") {
    showFailToast("您的浏览器不支持WebSocket")
    return
  }
  //@ts-ignore
  if (scope as number == chatScopeEnum.PRIVATE_CHAT) {
    if (currentUser.value.id == Number(id)) {
      showFailToast('不能和自己聊天')
      return
    }
  }
  // 默认过滤两侧空格
  if (!content.value.trim()) {
    showFailToast('请输入聊天内容')
    return
  }
  const message: messageRequest = {
    // @ts-ignore
    toId: scope as number == chatScopeEnum.PRIVATE_CHAT ? id : null,
    // @ts-ignore
    teamId: scope as number == chatScopeEnum.TEAM_CHAT ? id : null,
    content: content.value,
    fromId: currentUser.value.id,
    // @ts-ignore
    scope: route.path === '/hall_chat'
        ? chatScopeEnum.HALL_CHAT : scope,
  }
  socket.send(JSON.stringify(message))
  const newMessage: chatMessage = {
    content: content.value,
    createTime: dayjs().format("YYYY[年]MM[月]DD[日] HH:mm:ss"),
    fromUser: {
      avatarUrl: currentUser.value?.avatarUrl,
      userId: currentUser.value?.id,
      username: currentUser.value?.username
    },
    isAdmin: currentUser.value?.userRole == userRole.ADMIN_USERS,
    isMy: true,
    // @ts-ignore
    scope: route.path === '/hall_chat'
        ? chatScopeEnum.HALL_CHAT : scope,
  }
  messageList.value.push(newMessage)
  console.log('发送测试', messageList.value)
  // 滚动到最底部
  await nextTick(() => {
    scrollToBottom()
  })
  // 清空发送消息
  content.value = ''
}

const scrollToBottom = async () => {
  await nextTick(() => {
    if (chatContent.value) {
      chatContent.value.scrollTop = chatContent.value.scrollHeight;
    }
  })
}


</script>

<style scoped>
.chat-page {
  min-width: 375px;
  height: 550px;
}

.head {
  height: 30px;
  margin-top: -7px;
  width: 100%;
  align-self: center;
  font-size: 18px;
  text-align: center;
  font-weight: bold;
}

.send {
  display: flex;
  align-items: center;
  height: 3rem;

}

.van-cell-group {
  flex-grow: 1;
  --van-field-text-area-min-height: 2.5rem
}

.input {
  background-color: #DCDCDC;
  height: 2rem;
  font-size: 1.7rem;
  text-align: center;
}

.van-button {
  align-items: center;
  margin: 0 13px 0 auto;
  width: 20%;
  height: 70%;
}

</style>
